﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.Eventing.Reader;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using NetWorkHelper.Helper;
using NetWorkHelper.ICommond;
using NetWorkHelper.IModels;
using NetWorkHelper.ITool;

namespace NetWorkHelper.TCP.TcpServer
{
    public partial class AxTcpServer : Component
    {
        public AxTcpServer()
        {
            InitializeComponent();
        }

        public AxTcpServer(IContainer container)
        {
            container.Add(this);

            InitializeComponent();
        }
        #region 注册事件

        #region OnRecevice接收数据事件

        [Description("接收数据事件")]
        [Category("TcpServer事件")]
        public event EventHandler<TcpServerReceviceaEventArgs> OnRecevice;

        protected virtual void TcpServerRecevice(IClient iClient, byte[] data)
        {
            if (OnRecevice != null)
            {
                CommonMethod.EventInvoket(() =>
                {
                    try
                    {
                        OnRecevice(this, new TcpServerReceviceaEventArgs(iClient, data));
                        TcpServerGetLog(iClient, LogType.ReceviedData, ConvertStringManager.HexByteArrayToString(data));
                    }
                    catch (Exception ex)
                    {
                        TcpServerErrorMsg(string.Format("接收客户端数据时发生错误，错误原因：{0},行号{1}", ex.Message, ex.StackTrace));
                    }
                });
            }
        }

        #endregion

        #region OnErrorMsg返回错误消息事件

        [Description("错误消息")]
        [Category("TcpServer事件")]
        public event EventHandler<TcpServerErrorEventArgs> OnErrorMsg;

        protected virtual void TcpServerErrorMsg(string msg)
        {
            if (OnErrorMsg != null)
            {
                CommonMethod.EventInvoket(() => { OnErrorMsg(this, new TcpServerErrorEventArgs(msg)); });
            }
        }

        #endregion

        #region OnReturnClientCount用户上线下线时更新客户端在线数量事件

        [Description("用户上线下线时更新客户端在线数量事件")]
        [Category("TcpServer事件")]
        public event EventHandler<TcpServerReturnClientCountEventArgs> OnReturnClientCount;

        /// <summary>
        /// 用户上线下线时更新客户端在线数量事件
        /// </summary>
        /// <param name="count"></param>
        protected virtual void TcpServerReturnClientCount(int count)
        {
            try
            {
                if (OnReturnClientCount != null)
                {
                    CommonMethod.EventInvoket(() =>
                    {
                        OnReturnClientCount(this, new TcpServerReturnClientCountEventArgs(count));
                    });
                }
            }
            catch
            {
                TcpServerGetLog(null, LogType.Server, "Error:TcpServerReturnClientCount"); //记录}
            }
        }

        #endregion

        #region OnStateInfo监听状态改变时返回监听状态事件

        [Description("监听状态改变时返回监听状态事件")]
        [Category("TcpServer事件")]
        public event EventHandler<TcpServerStateEventArgs> OnStateInfo;

        protected virtual void TcpServerStateInfo(IClient iClient, string msg, SocketState state)
        {
            try
            {
                if (OnStateInfo != null)
                {
                    CommonMethod.EventInvoket(() => { OnStateInfo(this, new TcpServerStateEventArgs(iClient, msg, state)); });
                }
            }
            catch
            {

                TcpServerGetLog(null, LogType.Server, "Error:TcpServerStateInfo"); //记录}
            }
        }

        #endregion

        #region OnAddClient新客户端上线时返回客户端事件

        [Description("新客户端上线时返回客户端事件")]
        [Category("TcpServer事件")]
        public event EventHandler<TcpServerClientEventArgs> OnOnlineClient;

        protected virtual void TcpServerOnlineClient(IClient iclient)
        {
            try
            {
                if (OnOnlineClient != null)
                {
                    CommonMethod.EventInvoket(() => { OnOnlineClient(this, new TcpServerClientEventArgs(iclient)); });
                }
                TcpServerReturnClientCount(ClientNumber);
                TcpServerGetLog(iclient, LogType.Client, "客户端上线"); //记录
            }
            catch
            {
                TcpServerGetLog(null, LogType.Server, "Error:TcpServerOnlineClient"); //记录}
            }

        }

        #endregion

        #region OnOfflineClient客户端下线时返回客户端事件

        [Description("客户端下线时返回客户端事件")]
        [Category("TcpServer事件")]
        public event EventHandler<TcpServerClientEventArgs> OnOfflineClient;

        protected virtual void TcpServerOfflineClient(IClient iclient)
        {
            try
            {
                if (OnOfflineClient != null)
                {
                    CommonMethod.EventInvoket(() => { OnOfflineClient(this, new TcpServerClientEventArgs(iclient)); });
                }
                TcpServerReturnClientCount(ClientNumber);
                TcpServerGetLog(iclient, LogType.Client, "客户端下线"); //记录
            }
            catch
            {
                TcpServerGetLog(iclient, LogType.Server, "Error:TcpServerOfflineClient"); //记录
            }

        }

        #endregion

        #region OnGetLog服务端读写操作时返回日志消息

        [Description("服务端读写操作时返回日志消息")]
        [Category("TcpServer事件")]
        public event EventHandler<TcpServerLogEventArgs> OnGetLog;

        public void TcpServerGetLog(IClient temp, LogType logType, string logMsg)
        {
            try
            {
                if (OnGetLog != null)
                {
                    CommonMethod.EventInvoket(() => { OnGetLog(this, new TcpServerLogEventArgs(temp, logType, logMsg)); });
                }
            }
            catch
            {

                TcpServerGetLog(null, LogType.Server, "Error:TcpServerGetLog"); //记录}
            }
        }

        #endregion

        #region OnSendDateSuccess发送消息成功时返回成功消息事件

        [Description("发送消息成功时返回成功消息事件")]
        [Category("TcpServer事件")]
        public event EventHandler<TcpServerSendReturnEventArgs> OnSendDateSuccess;

        protected virtual void TcpServerSendDateSuccess(IClient temp, int byteLen)
        {
            try
            {
                if (OnSendDateSuccess != null)
                {
                    CommonMethod.EventInvoket(() => { OnSendDateSuccess(this, new TcpServerSendReturnEventArgs(temp, byteLen)); });
                }
                TcpServerGetLog(temp, LogType.SendDataResult, string.Format("发送成功，字节数：{0}", byteLen));
            }
            catch
            {

                TcpServerGetLog(null, LogType.Server, "Error:TcpServerSendDateSuccess"); //记录
            }
        }

        #endregion
        #endregion
        #region ITCPBASE 成员

        private int _port = 0;
        private string _fileLog = "";//记录地址，如果为空表示不记录
        //是否开启心跳检测
        private bool _isHeartCheck = true;
        //心跳检测间隔
        private int _checkTime = 3;
        private IPEndPoint _ipEndPoint = null;//终结点地址项目里面用
        /// <summary>
        /// 本地的终结点地址封装；
        /// </summary>
        internal IPEndPoint IpEndPoint
        {
            get
            {
                try
                {
                    IPAddress ipAddress = null;
                    if (ServerIp == "")
                        ipAddress = IPAddress.Any;
                    else
                        ipAddress = IPAddress.Parse(CommonMethod.HostnameToIp(ServerIp));
                    _ipEndPoint = new IPEndPoint(ipAddress, ServerPort);
                    _port = _ipEndPoint.Port;
                }
                catch { throw; }
                return _ipEndPoint;
            }
        }
        /// <summary>
        /// //客户端引擎是否已经启动;
        /// </summary>
        protected bool _engineStart = false;
        private string _ip = "";//服务器的IP地址
        /// <summary>
        /// ip地址设置和读取
        /// </summary>
        public string ServerIp
        {
            get { return _ip; }
            set { _ip = value; }
        }
        /// <summary>
        /// 端口号设置和读取
        /// </summary>
        public int ServerPort
        {
            get { return _port; }
            set { _port = value; }
        }
        /// <summary>
        /// 引擎是否已经启动;
        /// </summary>
        public bool EngineStart
        {
            get { return _engineStart; }
            set { _engineStart = value; }
        }
        /// <summary>
        /// 是否记录引擎历史记录；为空表示不记录
        /// </summary>
        public string FileLog
        {
            get { return _fileLog; }
            set { _fileLog = value; }
        }
        [Description("是否开启心跳检测")]
        [Category("TCP服务端")]
        public bool IsHeartCheck
        {
            get { return _isHeartCheck; }
            set { _isHeartCheck = value; }
        }

        [Description("心跳检测时间,单位：毫秒")]
        [Category("TCP服务端")]
        public int CheckTime
        {
            get { return _checkTime; }
            set { _checkTime = value; }
        }
        #endregion

        #region 基本属性区块
        private List<IClient> clients = null;//所有客户端
        private Socket listener = null;
        private Thread _heartThread = null;
        private int _clientMax = 255;//允许最多客户端数
        /// <summary>
        /// 当前客户端数量
        /// </summary>
        public int ClientNumber
        {
            get { return ClientSocketList.Count; }
        }
        /// <summary>
        /// 允许最多客户端数
        /// </summary>
        public int ClientMax
        {
            get { return _clientMax; }
            set
            {
                if (value > 100)
                    _clientMax = 100;
                else
                    _clientMax = value;
            }
        }
        /// <summary>
        /// 得到所有的客户端
        /// </summary>
        public List<IClient> ClientSocketList
        {
            get
            {
                if (clients == null)
                    clients = new List<IClient>();
                return clients;
            }
            set { clients = value; }
        }
        #endregion

        #region 启动以及接收客户端区块
        /// <summary>
        /// 启动引擎
        /// 启动服务器,如果没出现异常,说明启动成功
        /// </summary>
        public void StartEngine()
        {
            if (EngineStart)
                return;
            try
            {
                listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                listener.Bind(IpEndPoint);
                listener.Listen(200);
                TcpServerStateInfo(null, string.Format("服务端Ip:{0},端口:{1}已启动监听", ServerIp, ServerPort),
                    SocketState.StartListening);
                TcpServerGetLog(null, LogType.Server,
                    string.Format("服务端Ip:{0},端口:{1}已启动监听", string.IsNullOrEmpty(ServerIp) ? "本机所有IP" : ServerIp,
                        ServerPort));
                listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
                _heartThread = new Thread(HeartThread);
                _heartThread.IsBackground = true;
                _heartThread.Start();//把心跳方法加入到线程里面
                EngineStart = true;//启动成功
            }
            catch (Exception ex)
            {
                if (_heartThread != null)
                    StopEngine();
                TcpServerStateInfo(null, string.Format("服务端Ip:{0},端口:{1}启动监听失败", ServerIp, ServerPort),
                    SocketState.StartListeningError);
                TcpServerGetLog(null, LogType.Server, ex.Message);
            }
        }
        /// <summary>
        /// 当连接一个客户端之后的回调函数
        /// </summary>
        /// <param name="ar">TcpClient</param>
        private void AcceptCallback(IAsyncResult ar)
        {
            IClient iClient = null;
            try
            {
                if (listener != null)
                {

                    listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
                }
                else
                {
                    StopEngine();
                    return;
                }

            }
            catch (Exception ex)
            {
                TcpServerGetLog(iClient, LogType.Server, ex.Message);
                return;
            }
            try
            {
                if (listener != null)
                {
                    Socket handler = listener.EndAccept(ar);
                    iClient = new IClient(handler);
                    Thread threadLongin = new Thread(LoginInitialization);
                    threadLongin.IsBackground = true;
                    threadLongin.Start(iClient); //启动客户验证系统
                }
            }
            catch
            {
            }
        }
        #endregion


        #region 接收到数据区块
        /// <summary>
        /// 当接收到数据之后的回调函数
        /// </summary>
        /// <param name="ar"></param>
        private void ReadCallback(IAsyncResult ar)
        {
            IClient iClient = (IClient)ar.AsyncState;
            Socket handler = iClient.WorkSocket;
            try
            {
                int bytesRead = handler.EndReceive(ar);
                if (bytesRead > 0)
                {

                    byte[] bytes = new byte[bytesRead];
                    Array.Copy(iClient.BufferInfo.ReceivedBuffer, 0, bytes, 0, bytesRead);
                    iClient.WorkSocket.BeginReceive(iClient.BufferInfo.ReceivedBuffer, 0,
                        iClient.BufferInfo.ReceivedBuffer.Length, 0,
                        new AsyncCallback(ReadCallback), iClient);

                    #region WebSocket验证
                    //验证websocket握手协议
                    //if (iClient.ClientStyle == ClientStyle.None)
                    //{
                    //    //string clientRecevieStr = ASCIIEncoding.Default.GetString(iClient.BufferInfo.ReceivedBuffer, 0, bytesRead);
                    //    ////如果客户端不存在则退出检测
                    //    //byte[] handShake=PackHandShakeData(GetSecKeyAccetp(bytes, bytesRead));
                    //    //if (handShake.Length > 0)
                    //    //{
                    //    //    iClient.ClientStyle = ClientStyle.WebSocket;
                    //    //    iClient.WorkSocket.Send(handShake);
                    //    //}
                    //    //else { iClient.ClientStyle = ClientStyle.PcSocket; }
                    //}
                    //if (iClient.ClientStyle == ClientStyle.WebSocket)
                    //{
                    //    string webstr = AnalyticData(bytes, bytes.Length);
                    //    string clientRecevieStr = webstr;
                    //    bytes = Encoding.Default.GetBytes(clientRecevieStr);
                    //}
                    #endregion

                    TcpServerRecevice(iClient, bytes);
                    //byte[] haveDate = ReceiveDateOne.DateOneManage(stateOne, bytesRead);//接收完成之后对数组进行重置
                    //handler.BeginReceive(iClient.BufferInfo.ReceivedBuffer, 0, stateOne.Buffer.Length, 0, new AsyncCallback(ReadCallback), stateOne);
                    //TcpDateOne(stateOne, haveDate);
                }
                else
                {
                    TcpServerStateInfo(iClient, string.Format("<{0}：{1}>---下线", iClient.Ip, iClient.Port),
                SocketState.ClientOnOff);
                    RemoveClient(iClient, "客户端下线");
                }
            }
            catch (Exception Ex)
            {
                int i = Ex.Message.IndexOf("远程主机强迫关闭了一个现有的连接");
                if (i != -1)
                {
                    RemoveClient(iClient, Ex.Message);
                }
                iClient.WorkSocket.Close();
            }
        }

        // 检查一个Socket是否可连接
        private bool IsSocketConnected(Socket client)
        {
            bool blockingState = client.Blocking;
            try
            {
                byte[] tmp = new byte[1];
                client.Blocking = false;
                client.Send(tmp, 0, 0);
                return false;
            }
            catch (SocketException e)
            {
                // 产生 10035 == WSAEWOULDBLOCK 错误，说明被阻止了，但是还是连接的
                if (e.NativeErrorCode.Equals(10035))
                    return false;
                else
                    return true;
            }
            finally
            {
                client.Blocking = blockingState;    // 恢复状态
            }
        }

        public bool PingOC(String ips)
        {
            bool ret;
            Process p = new Process();
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = true;
            int i = 0;
            p.Start();
            p.StandardInput.WriteLine("ping -n 1 " + ips);
            p.StandardInput.WriteLine("exit");
            string strRst = p.StandardOutput.ReadToEnd();
            if (strRst.IndexOf("(100%") == -1)
            {
                ret = true;
            }
            else
            {
                ret = false;
            }
            p.Close();
            return ret;
        }
        #endregion


        #region websocket模块

        /// <summary>
        /// 打包握手信息
        /// </summary>
        /// <param name="secKeyAccept">Sec-WebSocket-Accept</param>
        /// <returns>数据包</returns>
        private static byte[] PackHandShakeData(string secKeyAccept)
        {
            if (string.IsNullOrEmpty(secKeyAccept))
            {
                return new byte[0];
            }
            var responseBuilder = new StringBuilder();
            responseBuilder.Append("HTTP/1.1 101 Switching Protocols" + Environment.NewLine);
            responseBuilder.Append("Upgrade: websocket" + Environment.NewLine);
            responseBuilder.Append("Connection: Upgrade" + Environment.NewLine);
            responseBuilder.Append("Sec-WebSocket-Accept: " + secKeyAccept + Environment.NewLine + Environment.NewLine);
            //如果把上一行换成下面两行，才是thewebsocketprotocol-17协议，但居然握手不成功，目前仍没弄明白！
            //responseBuilder.Append("Sec-WebSocket-Accept: " + secKeyAccept + Environment.NewLine);
            //responseBuilder.Append("Sec-WebSocket-Protocol: chat" + Environment.NewLine);

            return Encoding.UTF8.GetBytes(responseBuilder.ToString());
        }

        /// <summary>
        /// 生成Sec-WebSocket-Accept
        /// </summary>
        /// <param name="handShakeText">客户端握手信息</param>
        /// <returns>Sec-WebSocket-Accept</returns>
        private static string GetSecKeyAccetp(byte[] handShakeBytes, int bytesLength)
        {
            string handShakeText = Encoding.UTF8.GetString(handShakeBytes, 0, bytesLength);
            string key = string.Empty;
            Regex r = new Regex(@"Sec\-WebSocket\-Key:(.*?)\r\n");
            Match m = r.Match(handShakeText);
            if (m.Groups.Count != 0)
            {
                key = Regex.Replace(m.Value, @"Sec\-WebSocket\-Key:(.*?)\r\n", "$1").Trim();
            }
            if (key == "")
            {
                return string.Empty;
            }
            byte[] encryptionString = SHA1.Create().ComputeHash(Encoding.ASCII.GetBytes(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"));
            return Convert.ToBase64String(encryptionString);
        }

        /// <summary>
        /// 解析客户端数据包
        /// </summary>
        /// <param name="recBytes">服务器接收的数据包</param>
        /// <param name="recByteLength">有效数据长度</param>
        /// <returns></returns>
        private static string AnalyticData(byte[] recBytes, int recByteLength)
        {
            if (recByteLength < 2) { return string.Empty; }

            bool fin = (recBytes[0] & 0x80) == 0x80; // 1bit，1表示最后一帧  
            if (!fin)
            {
                return string.Empty;// 超过一帧暂不处理 
            }

            bool mask_flag = (recBytes[1] & 0x80) == 0x80; // 是否包含掩码  
            if (!mask_flag)
            {
                return string.Empty;// 不包含掩码的暂不处理
            }

            int payload_len = recBytes[1] & 0x7F; // 数据长度  

            byte[] masks = new byte[4];
            byte[] payload_data;

            if (payload_len == 126)
            {
                Array.Copy(recBytes, 4, masks, 0, 4);
                payload_len = (UInt16)(recBytes[2] << 8 | recBytes[3]);
                payload_data = new byte[payload_len];
                Array.Copy(recBytes, 8, payload_data, 0, payload_len);

            }
            else if (payload_len == 127)
            {
                Array.Copy(recBytes, 10, masks, 0, 4);
                byte[] uInt64Bytes = new byte[8];
                for (int i = 0; i < 8; i++)
                {
                    uInt64Bytes[i] = recBytes[9 - i];
                }
                UInt64 len = BitConverter.ToUInt64(uInt64Bytes, 0);

                payload_data = new byte[len];
                for (UInt64 i = 0; i < len; i++)
                {
                    payload_data[i] = recBytes[i + 14];
                }
            }
            else
            {
                Array.Copy(recBytes, 2, masks, 0, 4);
                payload_data = new byte[payload_len];
                Array.Copy(recBytes, 6, payload_data, 0, payload_len);

            }

            for (var i = 0; i < payload_len; i++)
            {
                payload_data[i] = (byte)(payload_data[i] ^ masks[i % 4]);
            }

            return Encoding.UTF8.GetString(payload_data);
        }


        /// <summary>
        /// 打包服务器数据
        /// </summary>
        /// <param name="message">数据</param>
        /// <returns>数据包</returns>
        private static byte[] PackData(string message)
        {
            byte[] contentBytes = null;
            byte[] temp = Encoding.UTF8.GetBytes(message);

            if (temp.Length < 126)
            {
                contentBytes = new byte[temp.Length + 2];
                contentBytes[0] = 0x81;
                contentBytes[1] = (byte)temp.Length;
                Array.Copy(temp, 0, contentBytes, 2, temp.Length);
            }
            else if (temp.Length < 0xFFFF)
            {
                contentBytes = new byte[temp.Length + 4];
                contentBytes[0] = 0x81;
                contentBytes[1] = 126;
                contentBytes[2] = (byte)(temp.Length & 0xFF);
                contentBytes[3] = (byte)(temp.Length >> 8 & 0xFF);
                Array.Copy(temp, 0, contentBytes, 4, temp.Length);
            }
            else
            {
                // 暂不处理超长内容  
            }

            return contentBytes;
        }
        #endregion

        #region 向客户端发送数据的区块
        /// <summary>
        /// 向客户端发送数据,最基础的发送
        /// </summary>
        /// <param name="iClient">iClient</param>
        /// <param name="data">发送的数据</param>
        public bool SendData(IClient iClient, byte[] data)
        {
            try
            {
                if (iClient == null || data == null || data.Length == 0)
                    return false;
                iClient.WorkSocket.BeginSend(data, 0, data.Length, 0, new AsyncCallback(SendCallback), iClient);
                return true;
            }
            catch (Exception Ex)
            {
                try
                {
                    int i = Ex.Message.IndexOf("远程主机强迫关闭了一个现有的连接");
                    if (i != -1)
                    {
                        IClient iclient = IpEndPointToClient(iClient.IpEndPoint);
                        RemoveClient(iclient, Ex.Message);
                    }
                    i = Ex.Message.IndexOf("中止了一个已建立的连接");
                    if (i != -1)
                    {
                        IClient iclient = IpEndPointToClient(iClient.IpEndPoint);
                        RemoveClient(iclient, Ex.Message);
                    }
                    i = Ex.Message.IndexOf("无法访问已释放对象");
                    if (i != -1)
                    {
                        IClient iclient = IpEndPointToClient(iClient.IpEndPoint);
                        RemoveClient(iclient, Ex.Message);
                    }
                }
                catch
                {
                }
                return false;

            }
        }
        /// <summary>
        /// 发送完数据之后的回调函数
        /// </summary>
        /// <param name="ar">Clicent</param>
        private void SendCallback(IAsyncResult ar)
        {
            IClient iClient = (IClient)ar.AsyncState;
            if (iClient == null)
                return;
            Socket handler = iClient.WorkSocket;
            try
            {
                int bytesSent = handler.EndSend(ar);
                iClient.HeartTime = DateTime.Now;
                TcpServerSendDateSuccess(iClient, bytesSent);
            }
            catch (Exception ex)
            {
                TcpServerErrorMsg(string.Format("发送数据后回调时发生错误，错误原因：{0},行号{1}", ex.Message, ex.StackTrace));
                TcpServerGetLog(iClient, LogType.SendDataResult, string.Format("发送失败，失败原因：{0},行号{1}", ex.Message, ex.StackTrace));
            }
        }
        #endregion

        #region 心跳线程以及释放资源的基础方法private
        /// <summary>
        /// 心跳线程
        /// </summary>
        private void HeartThread()
        {
            while (true)
            {
                Thread.Sleep(CheckTime * 1000);
                int i = 0;
                while (i < ClientSocketList.Count)
                {
                    if (ClientSocketList[i] == null)
                    {
                        ClientSocketList.RemoveAt(i);
                        continue;
                    }

                    if (!ClientSocketList[i].IsCheckHeart)
                    {
                        i++;
                        continue;
                    }

                    if ((int)(DateTime.Now - ClientSocketList[i].HeartTime).TotalSeconds > CheckTime * 4)//4次没有收到失去联系
                    {
                        //if (ClientSocketList[i].ClientInfo.ClientType != null && ClientSocketList[i].ClientInfo.ClientType.ToString().Equals("VehicleType"))
                        //{
                        //    RemoveClient(ClientSocketList[i], "客户端长期连接不上,将断开此客户端");
                        //    continue;
                        //}
                        RemoveClient(ClientSocketList[i], "客户端长期连接不上,将断开此客户端");
                        continue;
                    }
                    else
                    {
                        if (ClientSocketList[i].ClientInfo == null)
                        {

                            SendData(ClientSocketList[i], new byte[] { PasswordCode._heartbeatCode });
                        }
                        else if (ClientSocketList[i].ClientInfo.HeartCheckType == HeartCheckType.EncodingString)
                        {
                            SendData(ClientSocketList[i], Encoding.Default.GetBytes(ClientSocketList[i].ClientInfo.Heartbeat));
                        }
                        else if (ClientSocketList[i].ClientInfo.HeartCheckType == HeartCheckType.HexString)
                        {
                            SendData(ClientSocketList[i], ConvertStringManager.StringToHexByteArray(ClientSocketList[i].ClientInfo.Heartbeat));
                        }
                        else if (ClientSocketList[i].ClientInfo.HeartCheckType == HeartCheckType.Byte)
                        {
                            SendData(ClientSocketList[i], ClientSocketList[i].ClientInfo.HeartbeatByte);
                        }
                    }
                    i++;
                }
                if (EngineStart == false)
                    break;
            }
        }
        /// <summary>
        /// 关闭相连的scoket以及关联的TcpState,释放所有的资源
        /// </summary>
        /// <param name="iClient">TcpState</param>
        /// <param name="str">原因</param>
        public void RemoveClient(IClient iClient, string str)
        {
            try
            {
                if (iClient == null)
                    return;
                //iClient.WorkSocket.Disconnect();

                iClient.WorkSocket.Shutdown(SocketShutdown.Both);
                iClient.WorkSocket.Close();
                if (ClientSocketList.Remove(iClient))//当没有登录的时候断掉，不触发下面的事件
                {
                    TcpServerOfflineClient(iClient);
                }
            }
            catch (Exception exception)
            {
                try { iClient.WorkSocket.Close(); } catch { }

                if (ClientSocketList.Remove(iClient))//直接删除
                {
                    TcpServerOfflineClient(iClient);
                }
                TcpServerGetLog(null, LogType.Server, "Error:RemoveClient"); //记录
            }
            iClient = null;

        }
        /// <summary>
        /// 当客户端连接之后
        /// </summary>
        /// <param name="client">TcpState</param>
        private void LoginInitialization(object client)
        {
            if (client == null)
                return;
            IClient iClient = (IClient)client;
            if (ClientNumber >= _clientMax)
            {
                RemoveClient(iClient, "客户端数量已达到上限");
                return;
            }
            //Send(iClient, EncryptionDecryptVerification.EncryptionVerification(PasswordCode._serverToClient));//发送登录成功的代码
            try
            {
                ClientSocketList.Add(iClient);
                TcpServerOnlineClient(iClient);
                TcpServerStateInfo(iClient, string.Format("<{0}：{1}>---上线", iClient.Ip, iClient.Port),
                    SocketState.ClientOnline);
                TcpServerReturnClientCount(ClientNumber);
                iClient.WorkSocket.BeginReceive(iClient.BufferInfo.ReceivedBuffer, 0, iClient.BufferInfo.ReceivedBuffer.Length, 0, new AsyncCallback(ReadCallback), iClient);
            }
            catch
            {
            }
        }
        #endregion

        #region 客户需要操作的一些方法
        /// <summary>
        /// 关闭服务器,释放所有资源
        /// </summary>
        public void StopEngine()
        {
            try
            {
                if (_heartThread != null)
                    _heartThread.Abort();
                _heartThread = null;
                CloseAllClient();
                ClientSocketList.Clear();
                if (listener != null)
                {
                    listener.Close();
                    listener.Dispose();
                }
                listener = null;
                EngineStart = false; //停止服务
                TcpServerReturnClientCount(ClientSocketList.Count);
                TcpServerStateInfo(null, string.Format("服务端已停止监听"), SocketState.StopListening);
                TcpServerGetLog(null, LogType.Server, "服务端已停止监听");
            }
            catch
            {
            }
        }
        /// <summary>
        /// 关闭所有客户端连接
        /// </summary>
        public void CloseAllClient()
        {
            foreach (IClient client in ClientSocketList)
            {
                if (client == null)
                    continue;
                try
                {

                    client.WorkSocket.Shutdown(SocketShutdown.Both);
                    client.WorkSocket.Close();
                }
                catch (Exception ex)
                {

                }
                //RemoveClient(client, "服务器关闭所有的客户端");
            }
            ClientSocketList.Clear();
        }
        /// <summary>
        /// 服务器强制关闭一个客户端
        /// </summary>
        /// <param name="iClient">IPEndPoint</param>
        public void CloseClient(IClient iClient)
        {
            if (iClient == null || ClientNumber == 0)
                return;
            iClient.WorkSocket.Close();
            ClientSocketList.Remove(iClient);
        }
        /// <summary>
        /// 检查某个客户端是否在线
        /// </summary>
        /// <param name="ipEndPoint">IPEndPoint</param>
        /// <returns>bool</returns>
        public bool CheckClient(IPEndPoint ipEndPoint)
        {
            IClient iClient = IpEndPointToClient(ipEndPoint);
            if (iClient == null)
                return false;
            return true;
        }
        /// <summary>
        /// 服务器向客户端发送数据
        /// </summary>
        /// <param name="iClient">IPEndPoint</param>
        /// <param name="data">文本数据</param>
        public void SendData(IClient iClient, string data)
        {
            SendData(iClient, Encoding.Default.GetBytes(data));
        }
        /// <summary>
        /// 把ip地址转化成TcpState
        /// </summary>
        /// <param name="ipEndPoint">IPEndPoint</param>
        /// <returns>TcpState</returns>
        private IClient IpEndPointToClient(IPEndPoint ipEndPoint)
        {
            try
            {
                return ClientSocketList.Find(a => a.IpEndPoint.Equals(ipEndPoint));
            }
            catch { return null; }
        }

        #endregion
    }
}
